#include "HelloWindow.h"
#include <QExposeEvent>
#include <QResizeEvent>
#include <QKeyEvent>
#include <QCoreApplication>

HelloWindow::HelloWindow()
    : QWindow(),
      m_context(nullptr),
      m_update_pending(false)
{
    setSurfaceType(QWindow::OpenGLSurface);
    resize(800, 600);
    setTitle("LearnOpenGL");
}

void HelloWindow::renderNow()
{
    if (!isExposed())
        return;

    if (!m_context) {
        m_context = new QOpenGLContext(this);
        m_context->setFormat(requestedFormat());
        m_context->create();

        m_context->makeCurrent(this);

        initializeOpenGLFunctions();
        auto retinaScale = devicePixelRatio();
        glViewport(0, 0,
                   width() * retinaScale,
                   height() * retinaScale);
    }
    else {
        m_context->makeCurrent(this);
    }

    m_context->swapBuffers(this);
    renderLater();
}

void HelloWindow::renderLater()
{
    if (!m_update_pending) {
        m_update_pending = true;
        QCoreApplication::postEvent(this, new QEvent(QEvent::UpdateRequest));
    }
}

bool HelloWindow::event(QEvent *event) {
    switch (event->type()) {
    case QEvent::UpdateRequest:
        m_update_pending = false;
        renderNow();
        return true;
    default:
        return QWindow::event(event);
    }
}

void HelloWindow::exposeEvent(QExposeEvent *event)
{
    renderNow();
    return QWindow::exposeEvent(event);
}

void HelloWindow::resizeEvent(QResizeEvent *event)
{
    const auto &size = event->size();
    auto retinaScale = devicePixelRatio();
    if (m_context)
        glViewport(0, 0,
                   size.width() * retinaScale,
                   size.height() * retinaScale);
    renderNow();

    return QWindow::resizeEvent(event);
}

void HelloWindow::keyPressEvent(QKeyEvent *event)
{
    switch(event->key()) {
    case Qt::Key_Escape:
        close();
        return;
    default:
        return QWindow::keyPressEvent(event);
    }
}
